package com.experian.daas.litigation.config;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.experian.core.sharding.plugin.ShardPlugin;
import com.experian.core.sharding.sqlsessiontemplate.CustomSqlSessionTemplate;
import com.experian.core.sharding.sqlsessiontemplate.CustomerContextHolder;
import com.experian.core.tx.ChainedTransactionManager;
import com.github.pagehelper.PageHelper;

/**
 * mybatis配置
 * 
 * @author lixiongcheng
 *
 */
@Configuration
@EnableTransactionManagement
public class MyBatisConfig {

	// >>>>>>>>>>>>>>>>>>>>>第一个数据源开始<<<<<<<<<<<<<<<<<<<<
	@Bean
	@Primary
	public DataSource db1DataSource() throws Exception {
		Properties props = new Properties();
		props.put("driverClassName", "com.mysql.jdbc.Driver");
		props.put("url", "jdbc:mysql://localhost:3306/daas1?characterEncoding=utf-8");
		props.put("username", "root");
		props.put("password", "root");
		return DruidDataSourceFactory.createDataSource(props);
	}

	@Bean
	public SqlSessionFactoryBean db1SqlSessionFactoryBean(@Qualifier("db1DataSource") DataSource db1DataSource)
			throws Exception {
		SqlSessionFactoryBean fb = new SqlSessionFactoryBean();
		fb.setDataSource(db1DataSource);
		fb.setMapperLocations(
				new PathMatchingResourcePatternResolver().getResources("classpath*:com/experian/**/dao/xml/*.xml"));
		fb.setConfigLocation(
				new PathMatchingResourcePatternResolver().getResource("classpath:mybatis/mybatisConfig.xml"));
		// 添加插件
		fb.setPlugins(new Interceptor[] { pageHelper() ,new ShardPlugin()});
		return fb;
	}

	@Bean
	public DataSourceTransactionManager db1TransactionManager(@Qualifier("db1DataSource") DataSource db1DataSource)
			throws Exception {
		return new DataSourceTransactionManager(db1DataSource);
	}

	// >>>>>>>>>>>>>>>>>>>>>第一个数据源结束<<<<<<<<<<<<<<<<<<<<

	// >>>>>>>>>>>>>>>>>>>>>第二个数据源开始<<<<<<<<<<<<<<<<<<<<
	/**
	 * 第二个数据源
	 * 
	 * @return
	 * @throws Exception
	 */
	@Bean
	DataSource db2DataSource() throws Exception {
		Properties props = new Properties();
		props.put("driverClassName", "com.mysql.jdbc.Driver");
		props.put("url", "jdbc:mysql://localhost:3306/daas2?characterEncoding=utf-8");
		props.put("username", "root");
		props.put("password", "root");
		return DruidDataSourceFactory.createDataSource(props);
	}

	@Bean
	public SqlSessionFactoryBean db2SqlSessionFactoryBean(@Qualifier("db2DataSource") DataSource db2DataSource)
			throws Exception {
		SqlSessionFactoryBean fb = new SqlSessionFactoryBean();
		fb.setDataSource(db2DataSource);
		fb.setMapperLocations(
				new PathMatchingResourcePatternResolver().getResources("classpath*:com/experian/**/dao/xml/*.xml"));
		fb.setConfigLocation(
				new PathMatchingResourcePatternResolver().getResource("classpath:mybatis/mybatisConfig.xml"));
		fb.setPlugins(new Interceptor[] { pageHelper() ,new ShardPlugin()});
		return fb;
	}

	@Bean
	public DataSourceTransactionManager db2TransactionManager(@Qualifier("db2DataSource") DataSource db2DataSource)
			throws Exception {
		return new DataSourceTransactionManager(db2DataSource);
	}

	// >>>>>>>>>>>>>>>>>>>>>第二个数据源结束<<<<<<<<<<<<<<<<<<<<

	/**
	 * 多数据源事物管理器
	 * 
	 * @param dtm1
	 * @param dtm2
	 * @return
	 */
	@Bean
	@Primary
	public ChainedTransactionManager chainedTransactionManager(
			@Qualifier("db1TransactionManager") DataSourceTransactionManager dtm1,
			@Qualifier("db2TransactionManager") DataSourceTransactionManager dtm2) {
		return new ChainedTransactionManager(dtm1, dtm2);
	}

	/**
	 * customSqlSessionTemplate 配置
	 * 
	 * @param sfb1
	 * @param sfb2
	 * @return
	 * @throws Exception
	 */
	@Bean(name = "customSqlSessionTemplate")
	public CustomSqlSessionTemplate customSqlSessionTemplate(
			@Qualifier("db1SqlSessionFactoryBean") SqlSessionFactoryBean sfb1,
			@Qualifier("db2SqlSessionFactoryBean") SqlSessionFactoryBean sfb2) throws Exception {
		CustomSqlSessionTemplate cst = new CustomSqlSessionTemplate(sfb1.getObject());
		Map<Object, SqlSessionFactory> targetSqlSessionFactorys = new HashMap<Object, SqlSessionFactory>();
		targetSqlSessionFactorys.put(CustomerContextHolder.DB1, sfb1.getObject());
		targetSqlSessionFactorys.put(CustomerContextHolder.DB2, sfb2.getObject());
		cst.setTargetSqlSessionFactorys(targetSqlSessionFactorys);
		return cst;
	}

	/**
	 * mybatis Dao扫描配置
	 * 
	 * @param customSqlSessionTemplate
	 * @return
	 */
	@Bean
	public MapperScannerConfigurer mapperScannerConfigurer(CustomSqlSessionTemplate customSqlSessionTemplate) {
		MapperScannerConfigurer msc = new MapperScannerConfigurer();
		msc.setBasePackage("com.experian.**.dao");
		msc.setSqlSessionTemplateBeanName("customSqlSessionTemplate");
		return msc;
	}

	/**
	 * pageHelper 插件
	 * @return
	 */
	private PageHelper pageHelper() {
		PageHelper pageHelper = new PageHelper();
		Properties properties = new Properties();
		properties.setProperty("reasonable", "true");
		properties.setProperty("supportMethodsArguments", "true");
		properties.setProperty("returnPageInfo", "check");
		properties.setProperty("params", "count=countSql");
		properties.setProperty("dialect", "mysql");
		pageHelper.setProperties(properties);
		return pageHelper;
	}

}